﻿<#
.DESCRIPTION
    Checks for installed updates against a list of recommended updates.
.PARAMETER featureOrRoleToValidate
    A string containing the list of features or roles to check update for. If not specified,
    the roles/features will be polled from the server.
.NOTES
    Will only work with Windows Server 2012 and up.
    Author: Mathieu Isabel   
#>
Function Validate-RecommendedUpdateStatus($featureOrRoleToValidate,$recommendedUpdatesListPath,$strictFeatureValidation)
{
   

    begin
    {
        if($recommendedUpdatesListPath -eq $null)
        {
            $recommendedUpdatesListPath=".\RecommendedUpdates.csv"
        }

        $recommendedUpdates=Import-Csv -Path $recommendedUpdatesListPath
        
        
        
    }
    process
    {
        $computerName=$_
        $installedKB=Get-HotFix -ComputerName $_
        $computerOperatingSystemVersion=(Get-WmiObject -ComputerName $computerName -Class Win32_OperatingSystem).Version
        $recommendedUpdatesToValidate=@()

        if($null -eq $featureOrRoleToValidate)
        {
            $installedRolesOrFeatures=(Get-WindowsFeature -ComputerName $computerName | Where-Object {$_.InstallState -eq "Installed"} | Select-Object Name).Name

            
            foreach($installedRoleOrFeature in $installedRolesOrFeatures)
            {
                $recommendedUpdatesToValidate+=$recommendedUpdates | Where-Object {$_.RecommendedForFeatureOrRole -like "*$installedRoleOrFeature*" -and $computerOperatingSystemVersion -like $_.OperatingSystemVersion} 
            }
        }
        else
        {
            if($strictFeatureValidation)
            {
                $recommendedUpdatesToValidate+=$recommendedUpdates | Where-Object {$_.RecommendedForFeatureOrRole -like "$featureOrRoleToValidate" -and $computerOperatingSystemVersion -like $_.OperatingSystemVersion}
            }
            else
            {
                $recommendedUpdatesToValidate+=$recommendedUpdates | Where-Object {$_.RecommendedForFeatureOrRole -like "*$featureOrRoleToValidate*" -and $computerOperatingSystemVersion -like $_.OperatingSystemVersion}
            }
        }

        $recommendedUpdatesToValidate=$recommendedUpdatesToValidate | Sort-Object -Property HotfixId,OperatingSystemVersion | Select-Object HotfixId,OperatingSystemVersion -Unique
        
        $finalRecommendedUpdatesToValidate=@()
        foreach($recommendedUpdateToValidate in $recommendedUpdatesToValidate)
        {
            $affectedFeaturesOrRoles=($recommendedUpdates | Where-Object {$_.HotfixId -eq $recommendedUpdateToValidate.HotfixId} | Select RecommendedForFeatureOrRole -Unique).RecommendedForFeatureOrRole -join ","
            $finalRecommendedUpdatesToValidate+=New-Object -TypeName PSObject -Property @{ HotfixId=$recommendedUpdateToValidate.HotfixId;
                                                                                           OperatingSystemVersion=$recommendedUpdateToValidate.OperatingSystemVersion;
                                                                                           AffectedFeaturesOrRoles=$affectedFeaturesOrRoles;
                                                                                           Status=($recommendedUpdates | Where-Object {$_.HotfixId -eq $recommendedUpdateToValidate.HotfixId})[0].Status;
                                                                                           Notes=($recommendedUpdates | Where-Object {$_.HotfixId -eq $recommendedUpdateToValidate.HotfixId})[0].Notes }
        }


        $finalRecommendedUpdatesToValidate | `
            Where-Object {$_.HotfixId -notin $installedKB.HotfixId.Replace("KB","") } | `
            Select-Object @{Name="ComputerName";Expression={$computerName}},HotfixId,@{Name="InstallStatus";Expression={"Missing"}},@{Name="KBURL";Expression={"https://support.microsoft.com/en-us/kb/"+$_.HotfixId}},AffectedFeaturesOrRoles,Status,Notes
        $finalRecommendedUpdatesToValidate | `
            Where-Object {$_.HotfixId -in $installedKB.HotfixId.Replace("KB","") } | `
            Select-Object @{Name="ComputerName";Expression={$computerName}},HotfixId,@{Name="InstallStatus";Expression={"Installed"}},@{Name="KBURL";Expression={"https://support.microsoft.com/en-us/kb/"+$_.HotfixId}},AffectedFeaturesOrRoles,Status,Notes
        
    }
}